home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Found / FWTaskG / Sources / FWLookup.asm next >
Encoding:
Assembly Source File  |  1995-11-08  |  5.7 KB  |  254 lines  |  [TEXT/MPS ]

  1. ;========================================================================================
  2. ;
  3. ;    File:                    FWLookup.asm
  4. ;    Release Version:    $ 1.0d11 $
  5. ;
  6. ;    Copyright:    1995 by Apple Computer, Inc., all rights reserved.
  7. ;
  8. ;========================================================================================
  9.     
  10.     LOCALS            ; Yes, we want local symbols on (those prefixed with a @@)
  11.     Model    Large    ; Large memory model
  12.     
  13.     %NOINCL
  14.     include    macros.asm
  15.  
  16.     public        _FW_PrivWinGetTaskGlobals, _FW_PrivWinSetTaskGlobals
  17.     extrn        ISTASK:far    ; FAR PASCAL IsTask(HTASK hTask)
  18.         
  19.         begdata
  20.  
  21. kMaxTasks            = 32
  22.  
  23. gCachedTaskID        DW    0
  24. gCachedTaskGPtr        DD    0
  25.  
  26. gTaskCount            DW    0
  27. gTaskIDArray        DW    kMaxTasks DUP (?)
  28. gTaskPtrArray        DD    kMaxTasks DUP (?)
  29.  
  30.         enddata
  31.         
  32.         begcode FWLookup
  33.         
  34. ;========================================================================================
  35. ;    PackTaskTable
  36. ;        Packs the task table, checking for tasks that have terminted
  37. ;        IsTask function is used to check if a task handle is still valid
  38. ;
  39. ;========================================================================================
  40.  
  41. PackTaskTable    PROC 
  42.  
  43.             WINENTER
  44.             
  45.             mov        cx, [gTaskCount]
  46.             jcxz    @@doReturn
  47.             
  48.             push    SI
  49.             mov        SI, OFFSET gTaskIDArray
  50.             cld                    ; scan forward
  51.             
  52.             ; start the loop
  53.     @@nextTaskID:
  54.             mov        AX, [SI]    ; get the next task ID
  55.             push    AX
  56.             call    ISTASK        ; check if the task is still valid
  57.             jnz        @@doNextTask
  58.             
  59.         ; the current task is not valid, remove the entry
  60.             dec        [gTaskCount]
  61.             dec        CX
  62.  
  63.             mov        DI, [gTaskCount]
  64.             shl        DI, 2
  65.             
  66.             mov        AX, [DI]
  67.             mov        [SI], AX
  68.             mov        AX, [DI + 2]
  69.             mov        [SI + 2], AX
  70.             
  71.             jmp        short @@doLoop    ; loop to the next, but don't increment the pointer
  72.         
  73.         ; flush the cache
  74.             mov        [gCachedTaskID], 0
  75.             
  76.     @@doNextTask:
  77.             inc        SI
  78.             inc        SI
  79.     @@doLoop:        
  80.             loop    @@nextTaskID
  81.             
  82.             pop        SI
  83.             
  84.     @@doReturn:            
  85.             WINLEAVE
  86.             retf
  87.  
  88. PackTaskTable ENDP
  89.  
  90. ;========================================================================================
  91. ;  FW_PrivWinGetTaskGlobals
  92. ;    Returns the global pointer associated with this task
  93. ;
  94. ;    Parameters:
  95. ;        None
  96. ;
  97. ;    Return value:        
  98. ;        The data pointer associated with the current task
  99. ;        If the current task is not in the table, a new item is allocated
  100. ;        The initial value for the data pointer is NULL
  101. ;        If a new item could not be allocated, the return value is -1
  102. ;========================================================================================
  103.  
  104. _FW_PrivWinGetTaskGlobals:
  105.  
  106.             ; get the task ID, placed at the top to improve caching on i486
  107.             mov        AX, SS
  108.  
  109. if LPTR
  110.             ; establish the DS
  111.             mov        DX, _DATA
  112.             push    DS
  113.             mov        DS, DX
  114. endif            
  115.                         
  116.             ; see if the task ID is the same as the cached one
  117.             cmp        AX, WORD PTR [gCachedTaskID]
  118.             jne        @@doSearch
  119.             
  120.             ; it is, just return the cached value
  121.             mov        AX, WORD PTR [gCachedTaskGPtr]
  122.             mov        DX, WORD PTR [gCachedTaskGPtr + 2]
  123.             
  124.             ; restore the DS and return
  125.             ; do not jump to the end: that flushes the instruction cache
  126. if LPTR
  127.             pop        DS
  128. endif            
  129.             retf
  130.             
  131.             ; search the table
  132.     @@doSearch:
  133.             push    DI                ; routines need to preserve SI and DI
  134.             
  135.             mov        DX, DS            ; scasw buffer is pointed by ES:DI
  136.             mov        CX, [gTaskCount]
  137.             mov        ES, DX
  138.             mov        DI, OFFSET gTaskIDArray
  139.             cld                        ; search forward
  140.             repnz    scasw
  141.             jnz        @@addNewTaskId
  142.             
  143.             ; the task is in the table, and DI points one past the entry
  144.             mov        gCachedTaskID, AX
  145.             sub        DI, OFFSET gTaskIDArray + 2
  146.             shl        DI, 2
  147.             mov        AX, WORD PTR ES:gTaskPtrArray[DI]
  148.             mov        DX, WORD PTR ES:gTaskPtrArray + 2[DI]
  149.             jmp        short @@cacheAndReturn
  150.                         
  151.             ; the task is not in the table, add a new one
  152.     @@addNewTaskId:        
  153.             cmp        [gTaskCount], kMaxTasks
  154.             jne        @@nowAddTask
  155.             call    PackTaskTable
  156.             cmp        [gTaskCount], kMaxTasks
  157.             je        @@tooManyTasks
  158.             
  159.     @@nowAddTask:
  160.             mov        ES:[DI], AX
  161.             mov        gCachedTaskID, AX
  162.             sub        DI, OFFSET gTaskIDArray
  163.             shl        DI, 2
  164.             xor        AX, AX            ; the initial data pointer value is 0
  165.             mov        DX, AX
  166.             mov        WORD PTR ES:gTaskPtrArray[DI], AX
  167.             mov        WORD PTR ES:gTaskPtrArray + 2[DI], DX
  168.             inc        [gTaskCount]
  169.             jmp        short @@cacheAndReturn
  170.         
  171.             ; too many tasks, return ((void*) -1)
  172.     @@tooManyTasks:
  173.             xor        AX, AX
  174.             dec        AX
  175.             mov        DX, AX
  176.             jmp        short @@returnAXDX
  177.             
  178.             ; store the value in the cache and return
  179.     @@cacheAndReturn:            
  180.             mov        WORD PTR [gCachedTaskGPtr], AX
  181.             mov        WORD PTR [gCachedTaskGPtr + 2], DX
  182.  
  183.             ; restore registers
  184.     @@returnAXDX:            
  185.             pop        DI
  186. if LPTR
  187.             pop        DS
  188. endif            
  189.  
  190.             ; return
  191.             retf
  192.  
  193. ;========================================================================================
  194. ;  FW_PrivWinSetTaskGlobals:
  195. ;    Sets the global pointer associated with this task
  196. ;
  197. ;    Parameters:
  198. ;        The data pointer to associate with the current task
  199. ;
  200. ;    Return value:        
  201. ;        1 if everything is kosher
  202. ;        0 if the current task is not in the table yet
  203. ;========================================================================================
  204.  
  205. _FW_PrivWinSetTaskGlobals PROC
  206.     ARG dataArg:DWORD
  207.  
  208.             WINENTER
  209.             
  210.             ; save registers
  211.             push    DI
  212.             
  213.             ; BX holds the return value
  214.             xor        BX, BX
  215.             
  216.             ; get the task ID
  217.             mov        AX, SS
  218.         
  219.             mov        CX, [gTaskCount]
  220.             mov        DX, DS            ; scasw buffer is pointed by ES:DI
  221.             mov        ES, DX
  222.             mov        DI, OFFSET gTaskIDArray
  223.             cld                        ; search forward
  224.             repnz    scasw
  225.             jnz        @@doReturn
  226.             
  227.             ; the search is successfull, ES:DI points one past the found entry
  228.             sub        DI, OFFSET gTaskIDArray + 2
  229.             shl        DI, 2
  230.             mov        AX, WORD PTR [dataArg]
  231.             mov        DX, WORD PTR [dataArg + 2]
  232.             mov        WORD PTR ES:gTaskPtrArray[DI], AX
  233.             mov        WORD PTR ES:gTaskPtrArray + 2[DI], DX
  234.  
  235.             ; invalidate the cache
  236.             mov        gCachedTaskID, 0
  237.             
  238.             ; return a value indicating success
  239.             inc        BX
  240.             
  241.             ; restore registers and return
  242.     @@doReturn:            
  243.             pop        DI
  244.             mov        AX, BX        ; put return value into AX
  245.             
  246.             WINLEAVE
  247.             retf
  248.         
  249. _FW_PrivWinSetTaskGlobals ENDP
  250.  
  251.         endcode FWLookup
  252.         end
  253.  
  254.